package com.weifly.egp.service.stock;

import com.weifly.egp.service.config.GridConfigService;
import com.weifly.egp.service.monitor.StockInfo;
import com.weifly.egp.service.monitor.StockMonitorService;
import com.weifly.egp.service.trade.StockTradeService;
import com.weifly.egp.util.HttpRequestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Calendar;
import java.util.List;

/**
 * 股票更新服务
 *
 * Created by weijianxin on 2018/8/20.
 */
public class StockUpdateService {

    public static final String STOCK_URL_PREFIX = "http://hq.sinajs.cn/list=";

    private Logger logger = LoggerFactory.getLogger(StockUpdateService.class);

    private boolean isRun = false;
    private long updatePriceInterval = 3 * 1000;   // 更新价格间隔时间
    private long lastUpdatePriceTime = 0;   // 最后一次更新价格时间
    private long updateOrderInterval = 10 * 1000;  // 更新委托间隔时间
    private long lastUpdateOrderTime = 0;  // 最后一次更新委托情况时间

    private StockMonitorService stockMonitorService;
    private StockTradeService stockTradeService;
    private GridConfigService gridConfigService;

    public StockMonitorService getStockMonitorService() {
        return stockMonitorService;
    }

    public void setStockTradeService(StockTradeService stockTradeService) {
        this.stockTradeService = stockTradeService;
    }

    public void setStockMonitorService(StockMonitorService stockMonitorService) {
        this.stockMonitorService = stockMonitorService;
    }

    public void setGridConfigService(GridConfigService gridConfigService) {
        this.gridConfigService = gridConfigService;
    }

    public synchronized void startUpdateEveryTime(){
        if(this.isRun){
            logger.warn("already run!");
            return;
        }
        this.isRun = true;

        Thread updateThread = new Thread(new Runnable() {
            public void run() {
                while(true){
                    if(!StockUpdateService.this.isRun){
                        break;
                    }

                    try{
                        StockUpdateService.this.doUpdate();
                    }catch(Exception e){
                        logger.error("更新股票失败", e);
                    }

                    try {
                        synchronized (this){
                            this.wait(StockUpdateService.this.updatePriceInterval);
                        }
                    } catch (InterruptedException e) {
                        logger.error("中断", e);
                    }
                }
            }
        }, "stockUpdateThread");
        updateThread.start();
    }

    private void doUpdate() throws Exception {
        if(!this.inTradeTime()){
            // logger.info("不在交易时间");
            return;
        }

        //logger.info("开始更新股票...");
        List<StockInfo> allStocks = this.stockMonitorService.getAllStock();
        if(allStocks==null || allStocks.isEmpty()){
            // logger.info("没有股票！");
            return;
        }

        StockCheckAction action = new StockCheckAction();
        StockUpdateContextImpl ctx = new StockUpdateContextImpl();
        ctx.setStockUpdateService(this);
        ctx.setStockTradeService(this.stockTradeService);
        ctx.setStockMonitorService(this.stockMonitorService);
        ctx.setGridConfigService(this.gridConfigService);

        for(StockInfo stockInfo : allStocks){
            action.check(stockInfo, ctx);
        }
    }

    // 在交易时间内，则返回true
    private boolean inTradeTime(){
        Calendar cale = Calendar.getInstance();
        // 周一至周五
        int dayOfWeek = cale.get(Calendar.DAY_OF_WEEK);
        if(dayOfWeek==Calendar.MONDAY || dayOfWeek==Calendar.TUESDAY || dayOfWeek==Calendar.WEDNESDAY || dayOfWeek==Calendar.THURSDAY || dayOfWeek==Calendar.FRIDAY){
            long nowTime = cale.getTimeInMillis();
            cale.set(Calendar.HOUR_OF_DAY, 9);
            cale.set(Calendar.MINUTE, 13);
            cale.set(Calendar.SECOND, 0);
            cale.set(Calendar.MILLISECOND, 0);
            long startTime = cale.getTimeInMillis();
            cale.set(Calendar.HOUR_OF_DAY, 15);
            cale.set(Calendar.MINUTE, 3);
            long endTime = cale.getTimeInMillis();
            // 9点13分 至 15点3分
            if(startTime<=nowTime && nowTime<=endTime){
                return true;
            }
        }

        return false;
    }

    private String getFullCode(String stockCode){
        String fullCode = null;
        if(stockCode.startsWith("6")){
            fullCode = "sh"+stockCode; // 上海股票
        }else if(stockCode.startsWith("5")){
            fullCode = "sh"+stockCode; // 上海ETF基金
        }else if(stockCode.startsWith("1")){
            fullCode = "sz"+stockCode; // 深圳ETF基金
        }else if(stockCode.startsWith("0") || stockCode.startsWith("3")){
            fullCode = "sz"+stockCode; // 深圳股票
        }else{
            return null;
        }
        return fullCode;
    }

    public StockPrice getStockPrice(String stockCode) {
        String fullCode = this.getFullCode(stockCode);
        if(fullCode==null){
            logger.warn("无法拼接fullCode："+fullCode);
            return null;
        }

        String url = STOCK_URL_PREFIX+fullCode;
        String stockInfoStr =  HttpRequestUtils.sendGet(url, "GBK");
        if(stockInfoStr==null){
            return null;
        }
        int startIdx = stockInfoStr.indexOf("\"");
        if(startIdx==-1){
            return null;
        }
        int endIdx = stockInfoStr.indexOf("\"", startIdx+1);
        if(endIdx==-1){
            return null;
        }
        String targetStr = stockInfoStr.substring(startIdx+1, endIdx);
        //System.out.println(targetStr);
        String[] infoParts = targetStr.split(",");
        if(infoParts.length<4){
            return null;
        }
        StockPrice priceInfo = new StockPrice();
        priceInfo.setNowPrice(Double.valueOf(infoParts[3]));
        priceInfo.setHighPrice(Double.valueOf(infoParts[4]));
        priceInfo.setLowPrice(Double.valueOf(infoParts[5]));
        priceInfo.setUpdateTime(System.currentTimeMillis());
        return priceInfo;
    }
}
